package com.jvup.common.support.base;

import androidx.annotation.NonNull;
import androidx.databinding.ViewDataBinding;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;

import static androidx.lifecycle.Lifecycle.State.DESTROYED;
import static androidx.lifecycle.Lifecycle.State.STARTED;

/**
 * 事件控制器基类，由于注入事查找构造方法比较麻烦固使用了类泛型来提供参数类型简化构造函数查找，所以子类必须指定类泛型类型否则会报错<br />
 * 目前还有一个点需要注意，如果后期有需要唯一化控制器，可以考虑从ViewModel继承实现，这样全局Activity控制范围都可以轻松获得一个唯一的控制器，且还能够自动回收。
 * @param <O> LifecycleOwner EventController提供给Activity和Fragment 固构造 EventController 需要提供 LifecycleOwner 接口以管理什么周期。
 */
public abstract class EventController<O extends LifecycleOwner> {

    /**
     * 控制器所有者，依附的生命周期对象。一般为 Activity 和 Fragment，响应其对应UI布局上的事件。监听依附对象的生命周期并关联相关行为。
     * 使用 {@link LifecycleOwner} 的泛型类型，在基类完成了生命周期关联，而将具体的类型留在具体实现中确定，方便控制器可以在具体实现时轻松与页面完成交互。
     */
    @NonNull
    protected final O owner;

    /**
     * 构建一个控制器，依赖一个生命周期宿主，并在宿主 CREATED 完成时进行 UI 页面绑定
     * @param lifecycleOwner  {@link LifecycleOwner} 宿主
     */
    public EventController(@NonNull O lifecycleOwner) {
        this.owner = lifecycleOwner;
        LifecycleObserverWrapper observerWrapper = new LifecycleObserverWrapper(this.owner);
        if(Lifecycle.State.CREATED.isAtLeast(owner.getLifecycle().getCurrentState())) {
            observerWrapper.activeStateChanged(true);
        }
        this.owner.getLifecycle().addObserver(observerWrapper);
    }

    /**
     * 这个方法需要完成将控制器绑定到宿主的 {@link ViewDataBinding} 中，
     * 这个方法会在宿主生命周期为 {@link Lifecycle.State#CREATED CREATED} 之后调用。
     * 通过指定泛型 <{@link O}> 类型为继承自 {@link BaseActivity} 或 {@link BaseFragment}后可以使用 owner.viewDataBinder() 获取 {@link ViewDataBinding}；
     * 这个方法可能会被调用多次，且在宿主为 Fragment 情况下 viewDataBinder() 可能为 null，应该做出判空防御。
     * 目前为了保留更多的灵活性按此实现，以后不需要灵活的情况可以考虑将绑定行为封装在基类里，由子类提供 variableId。
     */
    protected abstract void bindView();

    /**
     * 在激活时被调用，宿主生命周期进入 {@link Lifecycle.State#STARTED STARTED} 后被调用。
     */
    protected void onActive() {}

    /**
     * 在失活时被调用，宿主生命周期进入 {@link Lifecycle.State#DESTROYED DESTROYED} 后被调用。
     */
    protected void onInactive() {}

    /**
     * 在清理时被调用，宿主完全退出并销毁时被调用。
     */
    protected void onCleared() {}

    class LifecycleObserverWrapper implements LifecycleEventObserver {

        @NonNull
        final LifecycleOwner mOwner;

        boolean mActive;

        LifecycleObserverWrapper(@NonNull LifecycleOwner owner) {
            mOwner = owner;
        }

        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                detachObserver();
                activeStateChanged(false);
                onCleared();
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // 设置活动状态
            mActive = newActive;

            if (mActive) {
                try {
                    bindView();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                onActive();
            } else {
                onInactive();
            }
        }

        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

}